#ifndef _STDINT_H
#include <stdint.h>
#endif

#ifndef _STDIO_H
#include <stdio.h>
#endif

#ifndef _STDINT_H
#include <stdint.h>
#endif

#ifndef _STDLIB_H
#include <stdlib.h>
#endif

#ifndef _NTH_LIB_H
#include <nth-lib.h>
#endif

int main(void){

	int error = 0;

	const uint16_t op_max = 0xFFFE;

	uint16_t operand_one = 0;
	uint16_t operand_two = 0;
	uint32_t product = 0;

	uint16_t operand_one_buffer = 0;
	uint16_t operand_two_buffer = 0;
	uint32_t product_buffer = 0;

	struct Nth_Multiplication nth_multiplication;

	nth_multiplication.operand_one.number_length = sizeof(operand_one_buffer);
	nth_multiplication.operand_one.number_buffer = &operand_one_buffer;

	nth_multiplication.operand_two.number_length = sizeof(operand_two_buffer);
	nth_multiplication.operand_two.number_buffer = &operand_two_buffer;

	nth_multiplication.product.number_length = sizeof(product_buffer);
	nth_multiplication.product.number_buffer = &product_buffer;

	while (operand_one <= op_max){

		while (operand_two <= op_max){

			product = 0;
			product += operand_one;
			product *= operand_two;

			operand_one_buffer = operand_one;
			operand_two_buffer = operand_two;

			error = Multiply_Nth_Numbers(&nth_multiplication);

			if (error){

				fprintf(
					stderr,
					"Error multiplying %u * %u\n",
					operand_one,
					operand_two
				);

				error = 1;
				break;
			}

			if (product_buffer != product){

				fputc('\n', stderr);

				fprintf(stderr, "   %u\n", operand_one);
				fprintf(stderr, " * %u\n", operand_two);
				fprintf(stderr, " = %u\n", product);
				fprintf(stderr, "!= %u\n", product_buffer);

				fputc('\n', stderr);

				error = 1;
				break;
			}

			operand_two++;
		}

		if (error)
			break;

		operand_one++;
	}

	if (error)
		return 1;

	return 0;
}


